#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "ble_core.h"

#include "driver/gpio.h"
#include "driver/uart.h"

#define GATTS_TAG "GATTS_DEMO"

#define UART_BAUD_RATE 115200
#define UART_PORT_NUM UART_NUM_0 // ESP32-C2默认UART0（USB-JTAG）
#define BUF_SIZE (1024)
#define DATA_QUEUE_SIZE 10

// 定义BLE发送数据结构
typedef struct
{
    uint16_t handle; // 特征值句柄
    uint16_t len;    // 数据长度
    uint8_t *data;   // 数据指针
} ble_send_data_t;

// 定义数据结构
typedef struct
{
    uint16_t handle;
    uint16_t len;
    uint8_t *data;
} ble_data_t;
uint8_t conn_id = 0;
static QueueHandle_t ble_data_queue = NULL;
static QueueHandle_t uart_data_queue = NULL;

// BLE数据处理任务
static void data_process_task(void *arg)
{
    ble_data_t data;
    while (1)
    {
        if (xQueueReceive(ble_data_queue, &data, portMAX_DELAY) == pdTRUE)
        {
            // 处理接收到的BLE数据
            ESP_LOGI(GATTS_TAG, "Processing BLE data: handle=%d, len=%d", data.handle, data.len);
            for (int i = 0; i < data.len; i++)
            {
                printf("%02x ", data.data[i]);
            }
            printf("\n");

            // 释放内存
            free(data.data);
        }
    }
}

// 定义BLE特征值
#define BLE_SERVICE_UUID 0x00FF
#define BLE_CHAR_TX_UUID 0xFF01     // 用于发送数据的特征值UUID
#define BLE_CHAR_RX_UUID 0xFF02     // 用于接收数据的特征值UUID
#define BLE_ADV_NAME "ESP32C2-UART" // 广播名称

// BLE连接状态
static bool ble_connected = false;

// UART0数据接收任务（仅处理RX输入，不干扰TX日志输出）
static void uart_process_task(void *arg)
{
    // 定义缓存区（大小根据实际需求调整，此处设为512字节，足够容纳210字节数据+结束符）
    static uint8_t uart_rx_buf[512] = {0};
    static uint16_t uart_rx_len = 0;                  // 当前缓存区数据长度
    const uint16_t MAX_BUF_LEN = sizeof(uart_rx_buf); // 最大缓存长度

    uint8_t *read_buf = (uint8_t *)malloc(BUF_SIZE);
    if (!read_buf)
    {
        ESP_LOGE(GATTS_TAG, "Failed to allocate UART read buffer");
        return;
    }

    while (1)
    {
        // 读取UART数据（超时100ms，避免阻塞）
        int len = uart_read_bytes(UART_PORT_NUM, read_buf, BUF_SIZE, pdMS_TO_TICKS(100));
        if (len > 0)
        {
            ESP_LOGI(GATTS_TAG, "UART received %d bytes (total cached: %d)", len, uart_rx_len + len);

            // 检查缓存区是否足够容纳新数据，避免溢出
            if (uart_rx_len + len > MAX_BUF_LEN)
            {
                ESP_LOGE(GATTS_TAG, "UART buffer overflow! Clearing cache.");
                uart_rx_len = 0; // 溢出时清空缓存，避免脏数据
            }

            // 将新数据追加到缓存区
            memcpy(uart_rx_buf + uart_rx_len, read_buf, len);
            uart_rx_len += len;

            // 检查缓存区中是否包含结束符 "\r\n"
            // 从缓存区起始到当前长度-1（避免越界）查找 "\r\n"
            for (uint16_t i = 0; i < uart_rx_len - 1; i++)
            {
                if (uart_rx_buf[i] == '\r' && uart_rx_buf[i + 1] == '\n')
                {
                    // 找到结束符，提取有效数据（从0到i，不包含\r\n）
                    uint16_t data_len = i;
                    if (data_len > 0) // 避免空数据（仅\r\n的情况）
                    {
                        ESP_LOGI(GATTS_TAG, "Detected end符, sending %d bytes to BLE", data_len);

                        // 若BLE已连接，发送数据
                        if (ble_connected)
                        {
                            uint8_t *ble_data_buf = (uint8_t *)malloc(data_len);
                            if (ble_data_buf)
                            {
                                memcpy(ble_data_buf, uart_rx_buf, data_len);
                                // 发送到BLE
                                esp_err_t ret = ble_core_notify(
                                    conn_id,
                                    gl_profile_tab[PROFILE_A_APP_ID].char_handle,
                                    ble_data_buf,
                                    data_len);
                                if (ret != ESP_OK)
                                {
                                    ESP_LOGE(GATTS_TAG, "Failed to send data to BLE");
                                }
                                else
                                {
                                    ESP_LOGI(GATTS_TAG, "Forward to BLE:");
                                    for (int j = 0; j < data_len; j++)
                                    {
                                        printf("%02x ", ble_data_buf[j]);
                                    }
                                    printf("\n");
                                }
                                free(ble_data_buf); // 释放临时缓冲区
                            }
                        }
                        else
                        {
                            ESP_LOGW(GATTS_TAG, "BLE not connected, dropping %d bytes", data_len);
                        }
                    }

                    // 处理剩余数据（将\r\n之后的内容移到缓存区开头）
                    uint16_t remaining_len = uart_rx_len - (i + 2); // 减去\r\n的2字节
                    if (remaining_len > 0)
                    {
                        memmove(uart_rx_buf, uart_rx_buf + i + 2, remaining_len);
                    }
                    uart_rx_len = remaining_len; // 更新缓存长度
                    break;                       // 跳出循环，等待下一次数据
                }
            }
        }
        // 无数据时短暂休眠，降低CPU占用
        vTaskDelay(pdMS_TO_TICKS(10));
    }

    // 理论上不会执行到这里，按需释放
    free(read_buf);
}

static void ble_core_event_handler(ble_core_evt_t *evt)
{
    switch (evt->type)
    {
    case BLE_CORE_EVT_CONNECT:
        ESP_LOGI(GATTS_TAG, "BLE connected, conn_id=%d", evt->params.conn.conn_id);
        ble_connected = true;
        conn_id = evt->params.conn.conn_id;
        break;
    case BLE_CORE_EVT_DISCONNECT:
        ESP_LOGI(GATTS_TAG, "BLE disconnected, conn_id=%d", evt->params.conn.conn_id);
        ble_connected = false;
        // 断开后重新启动广告
        ble_core_advertise_start(BLE_ADV_NAME);
        break;
    case BLE_CORE_EVT_READ:
        ESP_LOGI(GATTS_TAG, "BLE read, handle=%d", evt->params.data.handle);
        break;
    case BLE_CORE_EVT_WRITE:
        ESP_LOGI(GATTS_TAG, "BLE write, handle=%d, len=%d",
                 evt->params.data.handle, evt->params.data.len);

        // 将数据放入队列
        if (ble_data_queue)
        {
            ble_data_t data = {
                .handle = evt->params.data.handle,
                .len = evt->params.data.len,
                .data = malloc(evt->params.data.len)};

            if (data.data)
            {
                memcpy(data.data, evt->params.data.data, evt->params.data.len);
                if (xQueueSend(ble_data_queue, &data, 0) != pdTRUE)
                {
                    free(data.data); // 如果队列已满，释放内存
                    ESP_LOGW(GATTS_TAG, "Data queue full, dropped data");
                }
            }
        }
        break;
    case BLE_CORE_EVT_NOTIFY_ENABLE:
        ESP_LOGI(GATTS_TAG, "BLE notify enabled");
        break;
    case BLE_CORE_EVT_NOTIFY_DISABLE:
        ESP_LOGI(GATTS_TAG, "BLE notify disabled");
        break;
    //---------------------------- 新增配网逻辑 ---------------------------
    case BLE_CORE_EVT_PROV_SAVED:
        ESP_LOGI("MAIN", "WiFi provisioned: SSID=%s, Password=%s",
                 evt->params.prov.ssid, evt->params.prov.password);
        // 4. WiFi初始化（保留原逻辑，补充日志）
        // 调用WiFi组件连接函数
        break;
    case BLE_CORE_EVT_PROV_FAILED:
        ESP_LOGE("MAIN", "WiFi provision failed");
        // 可选：重新启动广播，允许重试
        ble_core_advertise_start("ESP32C2-Board");
        break;
    //-------------------------------------------------------------------
    default:
        break;
    }
}

void app_main(void)
{
    // UART初始化（适配ESP32-C2晶振：主晶振40MHz，PLL 480MHz）
    uart_config_t uart_config = {
        .baud_rate = UART_BAUD_RATE,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_PLL_F40M,
    };
    ESP_ERROR_CHECK(uart_driver_install(UART_PORT_NUM, BUF_SIZE * 2, 0, 0, NULL, 0));
    ESP_ERROR_CHECK(uart_param_config(UART_PORT_NUM, &uart_config));
    ESP_LOGI(GATTS_TAG, "UART initialized successfully");

    // 初始化BLE为从机模式
    ble_core_init(ble_core_event_handler);
    ble_core_advertise_start(BLE_ADV_NAME);

    // 创建BLE数据队列
    ble_data_queue = xQueueCreate(DATA_QUEUE_SIZE, sizeof(ble_data_t));
    if (!ble_data_queue)
    {
        ESP_LOGE(GATTS_TAG, "Failed to create BLE data queue");
        return;
    }

    // 创建UART数据队列
    uart_data_queue = xQueueCreate(DATA_QUEUE_SIZE, BUF_SIZE);
    if (!uart_data_queue)
    {
        ESP_LOGE(GATTS_TAG, "Failed to create UART data queue");
        return;
    }

    // 创建BLE数据处理任务
    xTaskCreate(data_process_task, "data_process_task", 4096, NULL, 5, NULL);

    // 创建UART数据处理任务
    xTaskCreate(uart_process_task, "uart_process_task", 4096, NULL, 5, NULL);

    ESP_LOGI(GATTS_TAG, "BLE UART bridge started in peripheral mode");
}
